package org.javaboy.vhr.controller.salary;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.javaboy.vhr.model.RespBean;
import org.javaboy.vhr.model.SalaryInfo;
import org.javaboy.vhr.model.RespPageBean;
import org.javaboy.vhr.service.SalaryInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.util.List;

@RestController
@RequestMapping("/salary/info")
public class SalaryInfoController {
	private static final Logger logger = LoggerFactory.getLogger(SalaryInfoController.class);

	@Resource
	private SalaryInfoService salaryInfoService;

	/**
	 * 分页查询工资单信息
	 * @param page 当前页码
	 * @param size 每页大小
	 * @param employeeId 员工ID（可选）
	 * @param salaryMonth 工资月份（可选）
	 * @param departmentId 部门ID（可选）
	 * @param positionId 职位ID（可选）
	 * @return 分页查询结果
	 */
	@GetMapping("/page")
	public RespPageBean getSalaryInfoByPage(
			@RequestParam(defaultValue = "1") Integer page,
			@RequestParam(defaultValue = "10") Integer size,
			@RequestParam(required = false) Integer employeeId,
			@RequestParam(required = false) String salaryMonth,
			@RequestParam(required = false) Integer departmentId,
			@RequestParam(required = false) Integer positionId) {
		logger.info("接收到工资单分页查询请求，页码：{}，每页大小：{}，员工ID：{}，工资月份：{}，部门ID：{}，职位ID：{}",
		            page, size, employeeId, salaryMonth, departmentId, positionId);
		try {
			Page<SalaryInfo> result = salaryInfoService.getSalaryInfoByPage(page, size, employeeId, salaryMonth, departmentId, positionId);
			RespPageBean respPageBean = new RespPageBean();
			respPageBean.setTotal(result.getTotal());
			respPageBean.setData(result.getRecords());
			logger.info("工资单分页查询成功，总记录数：{}", result.getTotal());
			return respPageBean;
		} catch (Exception e) {
			logger.error("工资单分页查询失败", e);
			RespPageBean respPageBean = new RespPageBean();
			respPageBean.setTotal(0L);
			respPageBean.setData(null);
			return respPageBean;
		}
	}

	/**
	 * 添加工资单信息
	 * @param salaryInfo 工资单对象
	 * @return 响应结果
	 */
	@PostMapping("/add")
	public RespBean addSalaryInfo(@RequestBody SalaryInfo salaryInfo) {
		logger.info("添加工资单信息 - 员工ID: {}, 薪资月份: {}, 基本工资: {}",
		            salaryInfo.getEmployeeId(), salaryInfo.getSalaryMonth(), salaryInfo.getBasicSalary());
		try {
			if (salaryInfoService.addSalaryInfo(salaryInfo)) {
				logger.info("添加工资单信息成功 - ID: {}", salaryInfo.getId());
				return RespBean.ok("添加工资单成功");
			}
			logger.warn("添加工资单信息失败 - 员工ID: {}", salaryInfo.getEmployeeId());
			return RespBean.error("添加工资单失败");
		} catch (Exception e) {
			logger.error("添加工资单信息异常", e);
			return RespBean.error("添加工资单失败：" + e.getMessage());
		}
	}

	/**
	 * 更新工资单信息
	 * @param salaryInfo 工资单对象
	 * @return 响应结果
	 */
	@PutMapping("/update")
	public RespBean updateSalaryInfo(@RequestBody SalaryInfo salaryInfo) {
		logger.info("更新工资单信息 - ID: {}, 员工ID: {}, 薪资月份: {}",
		            salaryInfo.getId(), salaryInfo.getEmployeeId(), salaryInfo.getSalaryMonth());
		try {
			if (salaryInfoService.updateSalaryInfo(salaryInfo)) {
				logger.info("更新工资单信息成功 - ID: {}", salaryInfo.getId());
				return RespBean.ok("更新工资单成功");
			}
			logger.warn("更新工资单信息失败 - ID: {}", salaryInfo.getId());
			return RespBean.error("更新工资单失败");
		} catch (Exception e) {
			logger.error("更新工资单信息异常", e);
			return RespBean.error("更新工资单失败：" + e.getMessage());
		}
	}

	/**
	 * 根据ID删除工资单信息
	 * @param id 工资单ID
	 * @return 响应结果
	 */
	@DeleteMapping("/deleteid")
	public RespBean deleteSalaryInfo(@PathVariable Integer id) {
		logger.info("删除工资单信息 - ID: {}", id);
		try {
			if (salaryInfoService.deleteSalaryInfo(id)) {
				logger.info("删除工资单信息成功 - ID: {}", id);
				return RespBean.ok("删除工资单成功");
			}
			logger.warn("删除工资单信息失败 - ID: {}", id);
			return RespBean.error("删除工资单失败");
		} catch (Exception e) {
			logger.error("删除工资单信息异常", e);
			return RespBean.error("删除工资单失败：" + e.getMessage());
		}
	}

	/**
	 * 根据ID查询工资单信息
	 * @param id 工资单ID
	 * @return 响应结果
	 */
	@GetMapping("/queryid")
	public RespBean getSalaryInfoById(@Param("id") Integer id) {
		logger.info("查询工资单信息 - ID: {}", id);
		try {
			SalaryInfo salaryInfo = salaryInfoService.getSalaryInfoById(id);
			if (salaryInfo != null) {
				logger.info("查询工资单信息成功 - ID: {}, 员工ID: {}", id, salaryInfo.getEmployeeId());
				return RespBean.ok("查询成功", salaryInfo);
			}
			logger.warn("查询工资单信息不存在 - ID: {}", id);
			return RespBean.error("查询失败：工资单不存在");
		} catch (Exception e) {
			logger.error("查询工资单信息异常", e);
			return RespBean.error("查询失败：" + e.getMessage());
		}
	}

	/**
	 * 根据员工ID查询工资单信息列表
	 * @param employeeId 员工ID
	 * @return 响应结果
	 */
	@GetMapping("/employee/{employeeId}")
	public RespBean getSalaryInfoByEmployeeId(@PathVariable Integer employeeId) {
		logger.info("查询员工工资单信息 - 员工ID: {}", employeeId);
		try {
			List<SalaryInfo> salaryInfoList = salaryInfoService.getSalaryInfoByEmployeeId(employeeId);
			logger.info("查询员工工资单信息成功 - 员工ID: {}, 记录数: {}", employeeId, salaryInfoList.size());
			return RespBean.ok("查询成功", salaryInfoList);
		} catch (Exception e) {
			logger.error("查询员工工资单信息异常", e);
			return RespBean.error("查询失败：" + e.getMessage());
		}
	}

	/**
	 * 导出工资单信息为Excel文件
	 * @return Excel文件的二进制数据
	 */
    @GetMapping("/export")
    public ResponseEntity<byte[]> exportToExcel() {
        logger.info("导出工资单信息为Excel文件");
        try {
            List<SalaryInfo> salaryInfoList = salaryInfoService.getAllSalaryInfo();
    
            try (Workbook workbook = new XSSFWorkbook()) {
                Sheet sheet = workbook.createSheet("工资单信息");
    
                // 创建标题行
                Row headerRow = sheet.createRow(0);
                String[] headers = {
                    "员工ID", "员工姓名", "部门", "职位", "工资月份", "基本工资", "绩效工资",
                    "加班费", "其他补贴", "水电费扣除", "工作天数", "请假时数", "应发工资",
                    "社保扣除", "住房公积金扣除", "个人所得税", "实发工资", "备注"
                };
    
                for (int i = 0; i < headers.length; i++) {
                    Cell cell = headerRow.createCell(i);
                    cell.setCellValue(headers[i]);
                }
    
                // 填充数据
                int rowNum = 1;
                for (SalaryInfo info : salaryInfoList) {
                    Row row = sheet.createRow(rowNum++);
                    row.createCell(0).setCellValue(info.getEmployeeId());
                    row.createCell(1).setCellValue(info.getEmployee() != null ? info.getEmployee().getName() : "");
                    row.createCell(2).setCellValue(info.getEmployee() != null && info.getEmployee().getDepartment() != null ?
                            info.getEmployee().getDepartment().getName() : "");
                    row.createCell(3).setCellValue(info.getEmployee() != null && info.getEmployee().getPosition() != null ?
                            info.getEmployee().getPosition().getName() : "");
                    row.createCell(4).setCellValue(info.getSalaryMonth());
                    row.createCell(5).setCellValue(info.getBasicSalary());
                    row.createCell(6).setCellValue(info.getPerformanceSalary());
                    row.createCell(7).setCellValue(info.getOvertimePay());
                    row.createCell(8).setCellValue(info.getOthers());
                    row.createCell(9).setCellValue(info.getUtilityDeduction());
                    row.createCell(10).setCellValue(info.getWorkingDays());
                    row.createCell(11).setCellValue(info.getLeaveHours());
                    row.createCell(12).setCellValue(info.getPayableSalary());
                    row.createCell(13).setCellValue(info.getSocialInsuranceDeduction());
                    row.createCell(14).setCellValue(info.getHousingFundDeduction());
                    row.createCell(15).setCellValue(info.getTax());
                    row.createCell(16).setCellValue(info.getActualSalary());
                    row.createCell(17).setCellValue(info.getRemarks());
                }
    
                // 自动调整列宽
                for (int i = 0; i < headers.length; i++) {
                    sheet.autoSizeColumn(i);
                }
    
                // 将工作簿写入字节数组
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                workbook.write(outputStream);
                byte[] excelData = outputStream.toByteArray();
    
                // 设置响应头，文件名用UTF-8编码，防止中文乱码
                HttpHeaders responseHeaders = new HttpHeaders();
                responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
                String fileName = java.net.URLEncoder.encode("工资单信息.xlsx", "UTF-8");
                responseHeaders.setContentDispositionFormData("attachment", fileName);
    
                logger.info("Excel文件导出成功，记录数：{}", salaryInfoList.size());
                return new ResponseEntity<>(excelData, responseHeaders, HttpStatus.OK);
            }
        } catch (Exception e) {
            logger.error("导出Excel文件失败", e);
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}